﻿using System;
using System.Collections.Generic;
using Cjc.Calculation.ExpressionEngine.Excel;
using Microsoft.Scripting.Hosting;
using Microsoft.Scripting.Runtime;

namespace Cjc.Calculation.ExpressionEngine.Hosting
{
	public class Excel<TContext>
	{
		// Methods
		public static ScriptEngine CreateEngine()
		{
			return GetEngine( CreateRuntime() );
		}

		public static ScriptEngine CreateEngine( IDictionary<string, object> options )
		{
			return GetEngine( CreateRuntime( options ) );
		}

		public static LanguageSetup CreateLanguageSetup( IDictionary<string, object> options )
		{
			var setup = new LanguageSetup(
				typeof( TContext ).AssemblyQualifiedName,
				"Excel",
				"Excel;Excel;xls".Split( new char[] { ';' } ),
				".xls".Split( new char[] { ';' } ) );

			if ( options != null )
			{
				foreach ( var pair in options )
				{
					setup.Options.Add( pair.Key, pair.Value );
				}
			}

			return setup;
		}

		public static ScriptRuntime CreateRuntime()
		{
			return new ScriptRuntime( CreateRuntimeSetup( null ) );
		}

		public static ScriptRuntime CreateRuntime( IDictionary<string, object> options )
		{
			return new ScriptRuntime( CreateRuntimeSetup( options ) );
		}

		public static ScriptRuntimeSetup CreateRuntimeSetup( IDictionary<string, object> options )
		{
			ScriptRuntimeSetup setup = new ScriptRuntimeSetup
			{
				LanguageSetups = { CreateLanguageSetup( options ) }
			};

			if ( options != null )
			{
				object obj2;
				if ( ( options.TryGetValue( "Debug", out obj2 ) && ( obj2 is bool ) ) && ( (bool)obj2 ) )
				{
					setup.DebugMode = true;
				}
				if ( ( options.TryGetValue( "PrivateBinding", out obj2 ) && ( obj2 is bool ) ) && ( (bool)obj2 ) )
				{
					setup.PrivateBinding = true;
				}
			}
			return setup;
		}

		public static ScriptEngine GetEngine( ScriptRuntime runtime )
		{
			return runtime.GetEngineByTypeName( typeof( TContext ).AssemblyQualifiedName );
		}
	}
}